import React, { useState, useEffect, useRef, useCallback } from 'react';
import TimeRangeSelector from './components/TimeRangeSelector.jsx';
import './App.css';
import CryptoJS from 'crypto-js';

// 添加一个全局变量来跟踪加载状态
const mapScriptLoadPromise = {
  promise: null,
  resolve: null,
  reject: null
};

const App = () => {
  const [map, setMap] = useState(null);
  const [locationData, setLocationData] = useState([]);
  const [currentMarker, setCurrentMarker] = useState(null);
  const [pathLine, setPathLine] = useState(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentIndex, setCurrentIndex] = useState(0);
  const [playbackSpeed, setPlaybackSpeed] = useState(5);
  const [currentLocation, setCurrentLocation] = useState(null);
  const [locationAddress, setLocationAddress] = useState('');
  const playbackTimerRef = useRef(null);
  const mapContainerRef = useRef(null);
  const [isLoading, setIsLoading] = useState(false);
  const [pathData, setPathData] = useState([]);
  const [selectedTimeRange, setSelectedTimeRange] = useState('24h');
  const [mapConfig, setMapConfig] = useState(null);

  // 获取地图配置
  useEffect(() => {
    const fetchMapConfig = async () => {
      try {
        const response = await fetch('/api/config');
        const config = await response.json();
        console.log('获取到的地图配置:', config); // 添加日志
        setMapConfig({
          webApi: config.amapKey,  // 用于地图显示
          webService: config.amapWebServiceKey || config.amapKey,  // 用于地理编码
          webServiceSecret: config.amapWebServiceSecret  // 用于签名
        });
      } catch (error) {
        console.error('获取地图配置失败:', error);
      }
    };
    fetchMapConfig();
  }, []);

  // 生成签名
  const generateSignature = (params) => {
    // 1. 参数排序
    const sortedParams = Object.keys(params).sort().map(key => {
      return `${key}=${params[key]}`;
    });

    // 2. 拼接待签名字符串
    const signStr = sortedParams.join('&');
    
    // 3. 添加密钥
    const stringToSign = signStr + mapConfig.webServiceSecret;
    
    // 4. MD5加密
    return CryptoJS.MD5(stringToSign).toString();
  };

  // 加载地图脚本
  const loadMapScript = useCallback((key) => {
    if (window.AMap) {
      return Promise.resolve();
    }

    if (mapScriptLoadPromise.promise) {
      return mapScriptLoadPromise.promise;
    }

    mapScriptLoadPromise.promise = new Promise((resolve, reject) => {
      mapScriptLoadPromise.resolve = resolve;
      mapScriptLoadPromise.reject = reject;

      const script = document.createElement('script');
      script.src = `https://webapi.amap.com/maps?v=2.0&key=${key}&plugin=AMap.Scale,AMap.ToolBar,AMap.MapType,AMap.Geocoder`;
      script.async = true;
      script.onload = () => {
        mapScriptLoadPromise.resolve();
        mapScriptLoadPromise.promise = null;
      };
      script.onerror = (error) => {
        mapScriptLoadPromise.reject(error);
        mapScriptLoadPromise.promise = null;
      };
      document.head.appendChild(script);
    });

    return mapScriptLoadPromise.promise;
  }, []);

  // 初始化地图
  useEffect(() => {
    let isSubscribed = true;

    const initMap = async () => {
      if (!mapConfig?.webApi) {
        console.warn('等待地图配置加载...');
        return;
      }

      try {
        await loadMapScript(mapConfig.webApi);

        if (!isSubscribed) return;

        // 创建地图实例
        const newMap = new window.AMap.Map(mapContainerRef.current, {
          zoom: 11,
          center: [116.397428, 39.90923],
          resizeEnable: true
        });

        // 添加控件
        newMap.addControl(new window.AMap.Scale());
        newMap.addControl(new window.AMap.ToolBar());
        newMap.addControl(new window.AMap.MapType());

        // 添加点击地图事件监听器
        newMap.on('click', () => {
          if (!isSubscribed) return;
          setCurrentLocation(null);
          setLocationAddress('');
        });

        if (isSubscribed) {
        setMap(newMap);
        }
      } catch (error) {
        console.error('地图初始化失败:', error);
      }
    };

    initMap();

    return () => {
      isSubscribed = false;
      if (map) {
        map.destroy();
      }
    };
  }, [mapConfig, loadMapScript]);

  // 处理时间范围变化
  const handleTimeRangeChange = async (range) => {
    try {
      const params = new URLSearchParams();
      params.append('start', range.start);
      params.append('end', range.end);
      
      const response = await fetch(`/api/locations?${params}`);
      const data = await response.json();
      
      // 如果数据是直接的数组
      const locationArray = Array.isArray(data) ? data : (data.data || []);
      
      if (locationArray.length > 0) {
        console.log('获取到位置数据:', locationArray.length, '条记录');
        setLocationData(locationArray);
        displayPath(locationArray);
      } else {
        console.warn('没有找到位置数据');
      }
    } catch (error) {
      console.error('获取位置数据失败:', error);
    }
  };

  // 显示轨迹路径
  const displayPath = (data) => {
    console.log('开始显示路径，数据点数量:', data.length);
    
    if (!map) {
      console.error('地图未初始化');
      return;
    }
    
    if (!data || data.length < 2) {
      console.warn('数据点不足，无法绘制路径');
      return;
    }

    try {
      // 清除现有路径和标记
      if (pathLine) {
        console.log('清除现有路径');
        map.remove(pathLine);
        setPathLine(null);
      }
      // 清除所有已有的标记
      if (currentMarker) {
        map.remove(currentMarker);
        setCurrentMarker(null);
    }

    // 创建路径点数组
      const path = data.map(loc => {
        // 如果是字符串格式（纬度,经度）
        if (typeof loc === 'string') {
          const [lat, lng] = loc.split(',').map(Number);
          if (!isNaN(lat) && !isNaN(lng)) {
            return [lng, lat]; // 注意：高德地图使用 [经度, 纬度] 的顺序
          }
          return null;
        }
        // 如果是MongoDB返回的数据格式
        else if (typeof loc === 'object' && loc !== null) {
          const { latitude, longitude } = loc;
          if (typeof latitude === 'number' && typeof longitude === 'number') {
            return [longitude, latitude];
          }
        }
        console.error('无效的位置数据:', loc);
        return null;
      }).filter(point => point !== null);

      console.log('处理后的路径点数组:', path);

      if (path.length < 2) {
        console.warn('有效路径点不足，无法绘制路径');
        return;
      }

      // 创建轨迹点标记
      const markers = path.map((position, index) => {
        // 创建轨迹点标记
        const marker = new window.AMap.Marker({
          position,
          icon: new window.AMap.Icon({
            size: new window.AMap.Size(16, 16),  // 增大尺寸
            image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_bs.png',
            imageSize: new window.AMap.Size(16, 16)  // 增大尺寸
          }),
          offset: new window.AMap.Pixel(-8, -8),  // 调整偏移以保持居中
          zIndex: 90,
          clickable: true
        });

        // 添加点击事件
        marker.on('click', () => {
          // 阻止事件传播到地图
          map.setStatus({dragEnable: false});
          setTimeout(() => {
            map.setStatus({dragEnable: true});
          }, 0);

          setCurrentLocation(data[index]);
          setLocationAddress('正在获取地址...');
          getLocationAddress(position[0], position[1]).then(address => {
            setLocationAddress(address);
          }).catch(error => {
            console.error('获取地址失败:', error);
            setLocationAddress('获取地址失败');
          });
        });

        return marker;
      });

    // 创建折线
    const newPathLine = new window.AMap.Polyline({
      path: path,
      strokeColor: '#3366FF',
      strokeWeight: 6,
      strokeOpacity: 0.8,
      strokeStyle: 'solid',
      lineJoin: 'round',
        showDir: true,
        zIndex: 50
      });

      // 创建起点标记
      const startMarker = new window.AMap.Marker({
        position: path[0],
        icon: new window.AMap.Icon({
          size: new window.AMap.Size(32, 32),  // 增大起点标记尺寸
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/start.png',
          imageSize: new window.AMap.Size(32, 32)  // 增大起点标记尺寸
        }),
        offset: new window.AMap.Pixel(-16, -16),  // 调整偏移以保持居中
        zIndex: 100,
        clickable: true
      });

      // 添加起点点击事件
      startMarker.on('click', () => {
        // 阻止事件传播到地图
        map.setStatus({dragEnable: false});
        setTimeout(() => {
          map.setStatus({dragEnable: true});
        }, 0);

        setCurrentLocation(data[0]);
        setLocationAddress('正在获取地址...');
        getLocationAddress(path[0][0], path[0][1]).then(address => {
          setLocationAddress(address);
        }).catch(error => {
          console.error('获取地址失败:', error);
          setLocationAddress('获取地址失败');
        });
      });

      // 创建终点标记
      const endMarker = new window.AMap.Marker({
        position: path[path.length - 1],
        icon: new window.AMap.Icon({
          size: new window.AMap.Size(32, 32),  // 增大终点标记尺寸
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/end.png',
          imageSize: new window.AMap.Size(32, 32)  // 增大终点标记尺寸
        }),
        offset: new window.AMap.Pixel(-16, -16),  // 调整偏移以保持居中
        zIndex: 100,
        clickable: true
      });

      // 添加终点点击事件
      endMarker.on('click', () => {
        // 阻止事件传播到地图
        map.setStatus({dragEnable: false});
        setTimeout(() => {
          map.setStatus({dragEnable: true});
        }, 0);

        setCurrentLocation(data[data.length - 1]);
        setLocationAddress('正在获取地址...');
        getLocationAddress(path[path.length - 1][0], path[path.length - 1][1]).then(address => {
          setLocationAddress(address);
        }).catch(error => {
          console.error('获取地址失败:', error);
          setLocationAddress('获取地址失败');
        });
      });

      // 批量添加到地图
      map.add([newPathLine, ...markers, startMarker, endMarker]);
    setPathLine(newPathLine);

    // 调整地图视图以显示整个路径
      map.setFitView([newPathLine, startMarker, endMarker]);

      // 创建当前位置标记（用于回放）
      const newCurrentMarker = new window.AMap.Marker({
        position: path[0],
        icon: new window.AMap.Icon({
          size: new window.AMap.Size(20, 20),  // 增大当前位置标记尺寸
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_r.png',
          imageSize: new window.AMap.Size(20, 20)  // 增大当前位置标记尺寸
        }),
        offset: new window.AMap.Pixel(-10, -10),  // 调整偏移以保持居中
        zIndex: 110
      });

      map.add(newCurrentMarker);
      setCurrentMarker(newCurrentMarker);

      // 更新当前位置信息，但不请求地址
      if (data[0]) {
        setCurrentLocation(data[0]);
        setLocationAddress(''); // 清空地址信息
      }
    } catch (error) {
      console.error('创建或显示路径时出错:', error);
    }
  };

  // 获取地址信息
  const getLocationAddress = async (longitude, latitude) => {
    if (!map || !mapConfig) return '地图未初始化';
    
    if (longitude < 73 || longitude > 135 || latitude < 18 || latitude > 53) {
      return '坐标超出服务范围';
    }
    
    try {
      // 准备请求参数
      const params = {
        key: mapConfig.webService,
        location: `${longitude},${latitude}`,
        radius: '1000',
        extensions: 'base',
        output: 'json'
      };

      // 生成时间戳和签名
      const timestamp = new Date().getTime();
      params.timestamp = timestamp;
      params.sig = generateSignature(params);
      
      // 构建URL
      const queryString = Object.entries(params)
        .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
        .join('&');
      
      const url = `https://restapi.amap.com/v3/geocode/regeo?${queryString}`;
      
      const response = await fetch(url);
      const data = await response.json();
      
      if (data.status === '1' && data.regeocode) {
        return data.regeocode.formatted_address || '未知地址';
      } else {
        throw new Error(`地理编码失败: ${data.info || '服务异常'}`);
      }
    } catch (error) {
      console.error('获取地址信息失败:', error);
      if (error.message.includes('INVALID_USER_KEY')) {
        return 'API密钥无效';
      } else if (error.message.includes('DAILY_QUERY_OVER_LIMIT')) {
        return '超出每日配额限制';
      } else if (error.message.includes('SERVICE_NOT_AVAILABLE')) {
        return '服务暂时不可用';
      } else if (error.message.includes('INVALID_USER_SIGNATURE')) {
        return 'API签名无效';
      }
      return '位置解析失败，请稍后重试';
    }
  };

  // 更新地图显示（播放时调用）
  const updateMapDisplay = useCallback((location, index) => {
    if (!map || !currentMarker) return;

    try {
      const position = [location.longitude, location.latitude];
      currentMarker.setPosition(position);

      // 为经过的点创建标记
      const passedMarker = new window.AMap.Marker({
        position: position,
        icon: new window.AMap.Icon({
          size: new window.AMap.Size(6, 6),
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
          imageSize: new window.AMap.Size(6, 6)
        }),
        offset: new window.AMap.Pixel(-3, -3),
        zIndex: 90,
        clickable: true
      });

      // 添加点击事件
      passedMarker.on('click', async () => {
        setCurrentLocation(location);
        setLocationAddress('正在获取地址...');
        try {
          const address = await getLocationAddress(location.longitude, location.latitude);
          setLocationAddress(address);
        } catch (error) {
          console.error('获取地址失败:', error);
          setLocationAddress('获取地址失败');
        }
      });

      map.add(passedMarker);

      // 更新位置信息但不自动获取地址
      setCurrentLocation(location);
    } catch (error) {
      console.error('更新地图显示失败:', error);
    }
  }, [map, currentMarker]);

  // 开始回放
  const startPlayback = () => {
    if (!locationData.length) return;
    
    setIsPlaying(true);
    const interval = 1000 / playbackSpeed;
    
    playbackTimerRef.current = setInterval(() => {
      setCurrentIndex(prevIndex => {
        if (prevIndex >= locationData.length) {
          stopPlayback();
          return 0;
        }
        
        updateMapDisplay(locationData[prevIndex], prevIndex);
        return prevIndex + 1;
      });
    }, interval);
  };

  // 暂停回放
  const pausePlayback = () => {
    setIsPlaying(false);
    if (playbackTimerRef.current) {
      clearInterval(playbackTimerRef.current);
    }
  };

  // 停止回放
  const stopPlayback = () => {
    pausePlayback();
    setCurrentIndex(0);
    if (locationData.length > 0) {
      updateMapDisplay(locationData[0], 0);
      // 清除位置信息显示
      setCurrentLocation(null);
      setLocationAddress('');
    }
  };

  // 处理速度变化
  const handleSpeedChange = (e) => {
    const newSpeed = parseInt(e.target.value);
    setPlaybackSpeed(newSpeed);
    
    if (isPlaying) {
      pausePlayback();
      startPlayback();
    }
  };

  const handleLoadData = async () => {
    setIsLoading(true);
    try {
      await handleTimeRangeChange({ start: 0, end: Date.now() });
    } catch (error) {
      console.error('加载数据失败:', error);
    } finally {
      setIsLoading(false);
    }
  };

  const handlePlayback = () => {
    startPlayback();
  };

  const handlePause = () => {
    pausePlayback();
  };

  const handleStop = () => {
    stopPlayback();
  };

  return (
    <div className="app-container">
      <header className="header">
        <h1>GPS轨迹追踪系统</h1>
      </header>

      <main className="main-content">
        <div className="map-container" ref={mapContainerRef}>
          {isLoading && (
            <div className="loading">
              <p>加载中...</p>
            </div>
          )}
          
          {currentLocation && (
            <div className="info-panel">
              <h3>位置信息</h3>
              <p>纬度: {currentLocation.latitude.toFixed(6)}</p>
              <p>经度: {currentLocation.longitude.toFixed(6)}</p>
              <p>时间: {new Date(currentLocation.timestamp).toLocaleString()}</p>
              {locationAddress && <p>地址: {locationAddress}</p>}
            </div>
          )}
        </div>

        <div className="control-panel">
          <div className="input-group">
            <label>时间范围</label>
            <TimeRangeSelector onTimeRangeChange={handleTimeRangeChange} />
          </div>

          <div className="btn-group">
            <button
              className="btn"
              onClick={handlePlayback}
              disabled={!locationData.length || isPlaying}
            >
              播放
            </button>
            <button
              className="btn"
              onClick={handlePause}
              disabled={!isPlaying}
            >
              暂停
            </button>
            <button
              className="btn"
              onClick={handleStop}
              disabled={!isPlaying && currentIndex === 0}
            >
              停止
            </button>
          </div>

          <div className="input-group">
            <label>播放速度</label>
            <div className="slider-group">
            <input
              type="range"
              min="1"
              max="10"
              value={playbackSpeed}
              onChange={handleSpeedChange}
            />
              <span>{playbackSpeed}x</span>
      </div>
          </div>
        </div>
      </main>
    </div>
  );
};

export default App; 